Linux内核:进程管理 您所在的位置:网站首页 linux 书 知乎 Linux内核:进程管理

Linux内核:进程管理

2023-04-07 04:51| 来源: 网络整理| 查看: 265

【推荐阅读】

Linux文件系统详解

linux进程管理---实时调度

linux内核内存管理-缺页异常

linux内核内存管理-brk系统调用

1.什么是进程同步?进程的并发性带来了异步性(各个并发的进程独立的以不可预知的速度向前推进),而有的进程则需要有次序的相互配合来完成作业,所以有了进程同步。进程同步 :在多道程序环境下,进程是并发执行的,不同进程之间存在着不同的相互制约关系,。为了协调进程之间的相互制约关系,引入了进程同步的概念。

临界资源虽然多个进程可以共享系统中的各种资源,但其中许多资源一段时间内只能为一个进程所使用,我们把一次仅允许一个进程使用的资源称为临界资源。许多物理设备都属于临界资源,如打印机等。此外,还有许多变量、数据等都可以被若干进程共享,也属于临界资源。

2.什么是进程互斥?对临界资源的访问,需要互斥的进行。同一个时间段内只允许一个进程访问该资源

临界资源的访问过程四个部分

进入区:为了进入临界区使用临界资源,在进入区要检查可否进入临界区,如果可以进入临界区,则应设置正在访问临界区的标志,以阻止其他进程同时进入临界区。临界区:进程中访问临界资源的那段代码,又称临界段。退出区:将正在访问临界区的标志清除。剩余区:代码中的其余部分。3.同步同步亦称直接制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调它们的工作次序而等待、传递信息所产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作。例如,输入进程A通过单缓冲向进程B提供数据。当该缓冲区空时,进程B不能获得所需数据而阻塞,一旦进程A将数据送入缓冲区,进程B被唤醒。反之,当缓冲区满时,进程A被阻塞,仅当进程B取走缓冲数据时,才唤醒进程A。4.互斥互斥亦称间接制约关系。当一个进程进入临界区使用临界资源时,另一个进程必须等待, 当占用临界资源的进程退出临界区后,另一进程才允许去访问此临界资源。例如,在仅有一台打印机的系统中,有两个进程A和进程B,如果进程A需要打印时, 系统已将打印机分配给进程B,则进程A必须阻塞。一旦进程B将打印机释放,系统便将进程A唤醒,并将其由阻塞状态变为就绪状态。互斥机制准则

为禁止两个进程同时进入临界区,互斥机制应遵循以下准则:空闲让进。临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区。忙则等待。当已有进程进入临界区时,其他试图进入临界区的进程必须等待。有限等待。对请求访问的进程,应保证能在有限时间内进入临界区。让权等待。当进程不能进入临界区时,应立即释放处理器,防止进程忙等待。

5.进程互斥的软件实现方法a.单标志法算法思想:一个进程在访问完临界区后会把权限交给另一个进程。也就是说一个进程访问临界区的权限只能被另一个进程所赋予。int turn = 0; //表示允许访问的进程号 //p0进程 while(turn != 0); //进入区 critical section; //临界区 turn = 1; //退出区 remainder section; //剩余区 //p1进程 while(turn != 1); critical section; //访问临界区 turn = 0; remainder section;假如p1先上处理机,p1会一直卡while循环,知道p1时间片被用完,发生调度。p0上处理机,p0顺利访问临界区,假如p0在访问临界区的时候发生调度切换到p1,p1依然会卡住,只有在p0执行完退出区的turn = 1这行代码时,p1才不会卡在while循环。所以这就验证了算法思想中的一个进程访问临界区的权限只能被另一个进程所赋予。也就实现了同一时刻只能由一个进程访问临界区资源,达到了进程互斥。但是这样也带来了问题,由于turn初始值为0,所以只能是p0,p1,p0,p1…这样轮流访问。假如p0一直不访问临界区,虽然临界区空闲,但是turn的值得不到改变,所以p1也访问不了临界区。这就违反了“空闲让进”准则(临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区)b.双标志先检查法算法思想:设置一个布尔型数组flag[ ],数组中各个元素,用来表示各个进程是否有访问临界区的意愿,true则是有,比如flag[0]=true表示0号进程现在想访问临界区。每个进程在访问临界区前,都会检查有没有其他想要访问临界区,如果没有,则把自身对应的flag[i]设置为true,表示该进程现在想要访问临界区。bool flag[2]; flag[0] = false, flag[1] = false; //p0进程 while(flag[1]); 1 flag[0] = true; 2 critical section; 3 flag[0] = false; 4 remainder section; //p1进程 while(flag[0]); 5 flag[1] = true; 6 critical section; 7 flag[1] = false; 8 remainder section;由于进程是并发执行的,所有一定会有并发性所带来的异步问题,则进程可能会按照1 5 2 6 3 7…这样的顺序来并发执行,则会造成"在同一时刻,有两个进程同时进入了临界区".所以双标志先检查法违反了“忙时等待”(当已有进程进入临界区时,其他试图进入临界区的进程必须等待)造成此问题的原因就是:"检查“和“上锁”不是原子操作,也就是说,检查 和 上锁之间有一个空隙,如果在这个空隙进程切换,则会导致该问题。c.双标志后检查法算法思想:双标志前检查法的改版,原来是先检查( while(flag[i]) )后上锁 (flag[i] = true)。这个则是先上锁后检查。bool flag[2]; flag[0] = false, flag[1] = false; //p0进程 flag[0] = true; 1 while(flag[1]); 2 critical section; 3 flag[0] = false; 4 remainder section; //p1进程 flag[1] = true; 5 while(flag[0]); 6 critical section; 7 flag[1] = false; 8 remainder section;由于并发带来的异步性,所以进程可能会 1 5 2 6…这样的顺序执行,这就导致两个进程都一直进不去临界区,同时违反了“空闲让进”和“有限等待”两个准则 ,并且两个进程一直访问不了临界区,则会产生“饥饿”现象。d.peterson算法算法思想:由于双标志后检查法两个进程都想先访问临界资源,而导致了“互不想让,且谁都访问不到”的局面。而 peterson算法则是如果双发都争着想访问临界资源,则可以让进程尝试,主动让对方先访问临界区。(“孔融让梨”,进程没有孔融那么人性化,它只会让一次“梨”)。bool flag[2]; flag[0] = false, flag[1] = false; int turn = 0;//表示“让”给其他进程 //p0进程 flag[0] = true; 1 turn = 1; 2 while(flag[1] && turn == 1); 3//如果1号进程想要使用临界区,而且我还让给它了,就等他一会吧 critical section; 4 flag[0] = false; 5 remainder section; //p1进程 flag[1] = true; 6 turn = 0; 7 while(flag[0] && turn ==0 ); 8//如果0号进程想要使用临界区,而且我还让给它了,就等他一会吧 critical section; 9 flag[1] = false; 10 remainder section;如果局面到了双标志后检查法“都想争着使用临界区的局面”的时候,这时候,一方会退一步,即让对方先使用临界区,这时候,这一方看到另一方都退一步了,所以自己也退了一步,最开始退一步的一方则向下执行了,使用临界区,使用完了之后,设置flag = false,即告诉对方我用完了,大哥你用吧。这个算法不会导致进程饥饿设置饿死的现象,另一个进程也遵守了“空闲让进,忙时等待,有限等待”的原则,但是还未遵循"让权等待的原则"。6.进程互斥的硬件实现方法

中断屏蔽方法

利用开/关中断指令 实现与原语中的实现思想相同,即在某进程开始访问临界区到访问结束为止都不允许中断也就是不能发生进程切换,因此不可能发生两个同时访问临界区的情况

关中断临界区开中断

其中的关中断 后继不允许当前进程被中断 也必然不会发生进程切换开中断 直到当前进程访问完临界区,在执行开中断指令,才有可能有别的进程上处理机并访问临界区

优点:简单高效缺点:不适合于多处理机,只适合用于操作系统内核进程,不适合于用户进程(开/关中断指令只能运行在内核态,这组指令如果能让用户随意使用会很危险)

TestAndSet指令

简称TS指令 或者是TSL指令使用硬件实现的 执行的过程不允许被中断 只能是一气呵成下面用C语言描述一下(稍微有点难理解 反正我看了好久好久)

//bool类型共享变量lock表示当前临界区是否被加锁 //true表示被加锁 false表示未加锁 bool TestAndSet(bool *lock){ bool old; old=*lock;//old用来存放lock原来的值 *lock=true;//无论之前是否被加锁 都把lock设置为加锁状态 return old;//返回原来的值 } //下面是TLS指令实现互斥算法的逻辑 while(TestAndSet(&lock));//上锁 并 检查 临界区代码段 lock=false;//临界区执行完毕 解锁 剩余区代码段

若刚开始lock是false(未加锁状态)则TSL返回的old是false,while循环条件不满足,直接跳过循环进入临界区若刚开始lock是true(加锁状态)则执行TLS之后返回的值是true while循环条件满足 一直会卡在这一步上等待临界区的代码段执行结束之后 lock自动解锁

相比软件方法 TLS指令将上锁 和 检查操作用硬件的方式变成了一气呵成的原子操作优点实现简单 无需像软件实现方法那样严格检查是否会有逻辑漏洞,适用于多处理机环境缺点不满足让权等带的原则,暂时无法进入临界区的进程会占用CPU并执行TSL指令,从而导致忙等

Swap指令

也叫Exchange指令 或者简称XCHG指令从逻辑上看Swap指令和TSL指令没有太大的区别

//Swap指令的作用就是交换两个变量的值 bool Swap(bool *a ,bool *b){ bool temp; temp=*a; *a=*b; *b=temp; }

//下面是TLS指令实现互斥算法的逻辑bool old=true;while(old==true)Swap(old,&lock);临界区代码段lock=false;//临界区执行完毕 解锁剩余区代码段

先记录此时临界区是否被上锁,再将lock设置为true,最后检查old如果old为false 说明之前没有其他的进程对临界区上锁 则跳出循环 进入临界区

优缺点同TSL相同

上边所写就是进程互斥的硬件实现方法 希望对大家有所帮助

总结【文章福利】小编推荐自己的Linux内核技术交流群:【977878001】整理一些个人觉得比较好得学习书籍、视频资料!进群私聊管理领取内核资料包(含视频教程、电子书、实战项目及代码)

内核资料直通车:Linux内核源码技术学习路线+视频教程代码资料

学习直通车:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈

原文作者:首页 - 内核技术中文网 - 构建全国最权威的内核技术交流分享论坛

原文地址:Linux内核:进程管理--进程间同步与互斥 - 圈点 - 内核技术中文网 - 构建全国最权威的内核技术交流分享论坛(版权归原文作者所有,侵权留言联系删除)



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有